package org.log4jconfig.xml.editor.contentassist.delegate;

import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.commons.lang.StringUtils;
import org.eclipse.jdt.core.Flags;
import org.eclipse.jdt.core.IJavaProject;
import org.eclipse.jdt.core.IMethod;
import org.eclipse.jdt.core.IType;
import org.eclipse.jdt.ui.ISharedImages;
import org.eclipse.wst.xml.core.internal.document.AttrImpl;
import org.eclipse.wst.xml.ui.internal.contentassist.ContentAssistRequest;
import org.log4jconfig.xml.editor.utils.JdtUtils;

@SuppressWarnings("restriction")
public class ParamContentAssistDelegatedProcessor extends
		AbstractContentAssistDelegatedProcessor {

	public void addAttributeValueProposals(
			ContentAssistRequest contentAssistRequest, String attributeName,
			String attributeCurrentValue, String attributeMatchValue)
			throws Exception {
		String parentNodeName = contentAssistRequest.getNode().getParentNode()
				.getNodeName();
		String className = ((AttrImpl) contentAssistRequest.getNode()
				.getParentNode().getAttributes().getNamedItem("class"))
				.getValueRegionText();
		className = StringUtils.replace(className, "\"", "");
		// retrieve type given its qualified name
		// TODO: move code to JdtUtils
		IJavaProject javaProject = JdtUtils.getCurrentJavaProject();
		IType type = javaProject.findType(className);
		List<String> proposalValues = new ArrayList<String>();
		Map<String, String> docs = new HashMap<String, String>();
		while (type != null) {
			for (IMethod method : type.getMethods()) {
				if (Flags.isPublic(method.getFlags())
						&& !Flags.isSynchronized(method.getFlags())
						&& !Flags.isAbstract(method.getFlags())
						&& method.getElementName().indexOf("set") == 0
						&& method.getParameterTypes().length == 1) {
					String value = method.getElementName().substring(3);
					if (filter(parentNodeName, value)) {
						proposalValues.add(value);
						docs.put(value, method.getAttachedJavadoc(null)); 
							
					}
				}
			}
			if (type.getSuperclassName() != null) {
				type = javaProject.findType(type.getSuperclassName());
			} else {
				type = null;
			}
		}
		// sort collection
		Collections.sort(proposalValues);
		// add all items
		for (String proposal : proposalValues) {
			super.addCompletionProposal(contentAssistRequest, proposal, docs.get(proposal), 
					attributeCurrentValue, attributeMatchValue,
					ISharedImages.IMG_FIELD_PUBLIC);
		}
	}

	/**
	 * Until I find a better way to exclude automatically some given parameter
	 * values, we need to remove them given the parent node and the actual DTD.
	 * 
	 * @param element
	 * @param value
	 * @return
	 */
	private boolean filter(String element, String value) {
		if (element.equalsIgnoreCase("appender")) {
			if (value.equalsIgnoreCase("Name")
					|| value.equalsIgnoreCase("Layout")) {
				return false;
			}
		}
		return true;
	}

}
